/*
 * Created by Jaren at 2022/10/28 17:42
 */
import 'dart:typed_data';

import 'package:binary/src/boxed_int.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/product_model.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/lorin/bean/euc/euc_settings.dart';
import 'package:inmotion_protocol/lorin/constant.dart';
import 'package:inmotion_protocol/util/byte_util.dart';
import 'package:inmotion_protocol/util/version.dart';

class V13Settings extends EucSettings {
  Uint16 overSpeedTiltBackThr = Uint16.zero;
  Uint16 overSpeedWarningThr = Uint16.zero;
  Uint16 overOutputTiltBackThr = Uint16.zero;
  Uint16 overOutputWarningThr = Uint16.zero;

  Uint8 maxChargeBatteryLevel = Uint8.zero;
  Uint8 maxDcOutputBatteryLevel = Uint8.zero;

  /// USB模式
  Uint8 usbMode = Uint8.zero;

  /// DRL开关
  Uint4 drlState = Uint4.zero;

  /// 照明灯自动开关
  Uint4 autoLightState = Uint4.zero;

  /// 照明灯亮度自动调节开关
  Uint4 autoLightBrightnessState = Uint4.zero;

  /// 手动设置的照明灯亮度，单位1%
  Uint8 lightBrightness = Uint8.zero;

  /// 风扇静音模式
  Uint4 fanQuietMode = Uint4.zero;

  /// 氛围灯模式
  Uint8 lightEffectMode = Uint8.zero;

  /// 远近光灯自动切换-近光灯切换速度阈值
  Uint8 autoLightLowThr = Uint8.zero;

  /// 远近光灯自动切换-远光灯切换速度阈值
  Uint8 autoLightHighThr = Uint8.zero;

  /// 自动息屏开关
  Uint4 autoScreenOff = Uint4.zero;

  /// 出厂安全限速开关
  Uint4 safeSpeedLimitState = Uint4.zero;

  /// 赛道倾角模式
  Uint4 bermAngleModeState = Uint4.zero;

  /// 是否允许切换至发烧者模式标识
  /// 此标识不代表已切换到发烧者模式，仅表示是否允许切换
  Uint4 allowFancyModeState = Uint4.zero;

  /// 密码类型; 0 - 无; 1 - 数字密码; 2 -手势密码; 3 - 滑动解锁
  Uint4 passwordType = Uint4.zero;

  /// 设备名称
  String deviceName = '';

  V13Settings(ProductModel model, VersionWrapper version) : super(model, version);

  @override
  void initCompact() {
    if (VersionUtils.higherOrEquals(version.getAppVersionByDevice(Constant.deviceEUCV13HMIC), "2.0.23")) {
      // 新增了是否允许切换至发烧者模式标识
      compact = _V13SettingsV1_5();
    } else if (VersionUtils.higherOrEquals(version.getAppVersionByDevice(Constant.deviceEUCV13HMIC), "2.0.22")) {
      // 新增了出厂安全限速开关和赛道倾角模式
      compact = _V13SettingsV1_4();
    } else {
      compact = _V13SettingsDefault();
    }
  }

  @override
  String toString() {
    return 'V13Settings{overSpeedTiltBackThr: $overSpeedTiltBackThr, overSpeedWarningThr: $overSpeedWarningThr, overOutputTiltBackThr: $overOutputTiltBackThr, overOutputWarningThr: $overOutputWarningThr, maxChargeBatteryLevel: $maxChargeBatteryLevel, maxDcOutputBatteryLevel: $maxDcOutputBatteryLevel, usbMode: $usbMode, drlState: $drlState, autoLightState: $autoLightState, autoLightBrightnessState: $autoLightBrightnessState, lightBrightness: $lightBrightness, fanQuietMode: $fanQuietMode, lightEffectMode: $lightEffectMode, autoLightLowThr: $autoLightLowThr, autoLightHighThr: $autoLightHighThr, autoScreenOff: $autoScreenOff, safeSpeedLimitState: $safeSpeedLimitState, bermAngleModeState: $bermAngleModeState, passwordType: $passwordType, deviceName: $deviceName}, ${super.toString()}';
  }
}

class _V13SettingsDefault extends Compact<V13Settings> {
  @override
  void fromBytes(V13Settings output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    output.overSpeedTiltBackThr = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.limitSpeed = output.overSpeedTiltBackThr;
    output.overSpeedWarningThr = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.overOutputTiltBackThr = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.overOutputWarningThr = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.pitchAngleZero = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.driveMode = ByteUtil.bitValue(bytes[offset], 0, 4);
    output.ridingMode = ByteUtil.bitValue(bytes[offset], 4, 4);
    offset++;
    output.comfortableDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.classicDriveModePedalSensitivity = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    output.speedingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.brakingFeedback = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.volume = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.soundPackId = ByteUtil.bytes2Uint32Le(bytes, offset);
    offset += 4;
    output.standbyTime = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.lightEffectMode = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightLowThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.autoLightHighThr = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.lightBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    output.maxChargeBatteryLevel = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;
    output.maxDcOutputBatteryLevel = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset++;

    // 保留2byte
    offset += 2;

    output.soundState = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.drlState = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.liftedState = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.autoLightState = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    output.autoLightBrightnessState = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.lockState = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.transportModeState = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.loadDetect = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    output.noLoadDetect = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.lowBatteryMode = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.fanQuietMode = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.soundWave = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    // 跳过2bit touch key
    output.usbPower = ByteUtil.bitValue(bytes[offset], 2, 4);
    output.remainderRangeEstimate = ByteUtil.bitValue(bytes[offset], 6, 2);
    offset++;
    output.assistBalance = ByteUtil.bitValue(bytes[offset], 0, 2);
    output.speedingBrakingFeedbackState = ByteUtil.bitValue(bytes[offset], 2, 2);
    // 其余保留
  }

  @override
  int length() {
    return 38;
  }
}

// ignore: camel_case_types
class _V13SettingsV1_4 extends _V13SettingsDefault {
  @override
  void fromBytes(V13Settings output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    super.fromBytes(output, bytes, offset);

    offset += 34;
    // 协议中，此功能名称为 出厂限速解锁开关，为对应此处变量名称，取值反一下
    output.safeSpeedLimitState = ByteUtil.toUint4(ByteUtil.bitValue(bytes[offset], 4, 1).value == 1 ? 0 : 1);
    output.bermAngleModeState = ByteUtil.bitValue(bytes[offset], 5, 1);
  }
}

// ignore: camel_case_types
class _V13SettingsV1_5 extends _V13SettingsV1_4 {
  @override
  void fromBytes(V13Settings output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + length()) {
      return;
    }
    super.fromBytes(output, bytes, offset);

    offset += 34;
    // 是否允许切换至发烧者模式
    output.allowFancyModeState = ByteUtil.bitValue(bytes[offset], 6, 1);
  }
}

class V13SettingsV1_5ImplDelegate extends _V13SettingsV1_5 {}
